package com.ruoyi.system.service.impl;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ThreadLocalRandom;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.system.domain.SysCodingRule;
import com.ruoyi.system.domain.SysCodingRuleSegment;
import com.ruoyi.system.mapper.SysCodingRuleMapper;
import com.ruoyi.system.mapper.SysCodingRuleSegmentMapper;
import com.ruoyi.system.service.ISysCodingService;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.DateUtils;

/**
 * 编码生成Service业务层处理
 * 
 * @author ruoyi
 * @date 2025-08-08
 */
@Service
public class SysCodingServiceImpl implements ISysCodingService 
{
    @Autowired
    private SysCodingRuleMapper sysCodingRuleMapper;
    
    @Autowired
    private SysCodingRuleSegmentMapper sysCodingRuleSegmentMapper;

    /**
     * 根据表名和字段名生成编码
     */
    @Override
    @Transactional
    public String generateCode(String tableName, String fieldName, Map<String, Object> params)
    {
        System.out.println("=== 开始生成编码 ===");
        System.out.println("表名: " + tableName);
        System.out.println("字段名: " + fieldName);
        System.out.println("参数: " + params);
        
        // 查询编码规则
        SysCodingRule codingRule = findCodingRule(tableName, fieldName);
        if (codingRule == null) {
            System.out.println("错误: 未找到编码规则");
            throw new RuntimeException("未找到表[" + tableName + "]字段[" + fieldName + "]的编码规则");
        }
        
        System.out.println("找到编码规则: " + codingRule.getRuleName());
        
        if (!"0".equals(codingRule.getStatus())) {
            System.out.println("错误: 编码规则已禁用");
            throw new RuntimeException("编码规则已禁用");
        }
        
        // 查询编码规则段
        SysCodingRuleSegment querySegment = new SysCodingRuleSegment();
        querySegment.setRuleId(codingRule.getRuleId());
        List<SysCodingRuleSegment> segments = sysCodingRuleSegmentMapper.selectSysCodingRuleSegmentList(querySegment);
        
        if (segments == null || segments.isEmpty()) {
            System.out.println("错误: 编码规则段配置为空");
            throw new RuntimeException("编码规则段配置为空");
        }
        
        System.out.println("找到编码规则段数量: " + segments.size());
        
        // 显示所有段的详细信息
        System.out.println("=== 发现重复规则段问题，共" + segments.size() + "个段 ===");
        for (int i = 0; i < segments.size(); i++) {
            SysCodingRuleSegment segment = segments.get(i);
            System.out.println("段" + (i+1) + ": ID=" + segment.getSegmentId() + ", 顺序=" + segment.getSegmentOrder() + ", 类型=" + segment.getSegmentType() + ", 值=" + segment.getSegmentValue() + ", 日期格式=" + segment.getDateFormat() + ", 流水号长度=" + segment.getSerialLength());
        }
        
        // 临时解决方案：只使用前3个段（正确的配置）
        if (segments.size() > 3) {
            System.out.println("检测到重复段配置，只使用前3个段");
            segments = segments.subList(0, 3);
        }
        
        // 按排序号排序
        segments.sort(Comparator.comparing(SysCodingRuleSegment::getSegmentOrder));
        
        // 生成编码
        StringBuilder codeBuilder = new StringBuilder();
        Date currentDate = new Date();
        
        System.out.println("开始生成各段编码:");
        for (int i = 0; i < segments.size(); i++) {
            SysCodingRuleSegment segment = segments.get(i);
            System.out.println("处理第" + (i+1) + "段: 类型=" + segment.getSegmentType() + ", 值=" + segment.getSegmentValue());
            
            String segmentValue = generateSegmentValue(segment, currentDate, codingRule);
            System.out.println("第" + (i+1) + "段生成结果: " + segmentValue);
            
            codeBuilder.append(segmentValue);
            
            // 添加分隔符（最后一段不加分隔符）
            if (i < segments.size() - 1 && StringUtils.isNotEmpty(codingRule.getSeparator())) {
                codeBuilder.append(codingRule.getSeparator());
                System.out.println("添加分隔符: " + codingRule.getSeparator());
            }
        }
        
        String finalCode = codeBuilder.toString();
        System.out.println("=== 编码生成完成 ===");
        System.out.println("最终生成的编码: " + finalCode);
        System.out.println("====================");
        
        return finalCode;
    }
    
    /**
     * 查找编码规则
     */
    private SysCodingRule findCodingRule(String tableName, String fieldName)
    {
        SysCodingRule query = new SysCodingRule();
        query.setTableName(tableName);
        query.setFieldName(fieldName);
        query.setStatus("0"); // 启用状态
        
        List<SysCodingRule> rules = sysCodingRuleMapper.selectSysCodingRuleList(query);
        System.out.println("查询到的编码规则数量: " + rules.size());
        for (int i = 0; i < rules.size(); i++) {
            SysCodingRule rule = rules.get(i);
            System.out.println("规则" + (i+1) + ": ID=" + rule.getRuleId() + ", 名称=" + rule.getRuleName());
        }
        return rules.isEmpty() ? null : rules.get(0);
    }
    
    /**
     * 生成段值
     */
    private String generateSegmentValue(SysCodingRuleSegment segment, Date currentDate, SysCodingRule codingRule)
    {
        String segmentType = segment.getSegmentType();
        
        switch (segmentType) {
            case "CONSTANT":
                return segment.getSegmentValue();
                
            case "FIXED":
                return segment.getSegmentValue();
                
            case "DATE":
                SimpleDateFormat dateFormat = new SimpleDateFormat(segment.getDateFormat());
                return dateFormat.format(currentDate);
                
            case "RANDOM":
                return generateRandomNumber(segment.getSerialLength() != null ? segment.getSerialLength().intValue() : null);
                
            default:
                throw new RuntimeException("不支持的段类型: " + segmentType);
        }
    }
    
    /**
     * 生成随机数
     */
    private String generateRandomNumber(Integer length)
    {
        if (length == null || length <= 0) {
            length = 6; // 默认6位
        }
        
        StringBuilder randomBuilder = new StringBuilder();
        for (int i = 0; i < length; i++) {
            randomBuilder.append(ThreadLocalRandom.current().nextInt(10));
        }
        
        return randomBuilder.toString();
    }
    


    /**
     * 编码预览
     */
    @Override
    public String previewCode(Map<String, Object> params)
    {
        String tableName = (String) params.get("tableName");
        String fieldName = (String) params.get("fieldName");
        
        if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(fieldName)) {
            throw new RuntimeException("表名和字段名不能为空");
        }
        
        // 查询编码规则
        SysCodingRule codingRule = findCodingRule(tableName, fieldName);
        if (codingRule == null) {
            throw new RuntimeException("未找到编码规则");
        }
        
        // 查询编码规则段
        SysCodingRuleSegment querySegment = new SysCodingRuleSegment();
        querySegment.setRuleId(codingRule.getRuleId());
        List<SysCodingRuleSegment> segments = sysCodingRuleSegmentMapper.selectSysCodingRuleSegmentList(querySegment);
        
        if (segments == null || segments.isEmpty()) {
            throw new RuntimeException("编码规则段配置为空");
        }
        
        // 按排序号排序
        segments.sort(Comparator.comparing(SysCodingRuleSegment::getSegmentOrder));
        
        // 生成预览编码（不更新流水号）
        StringBuilder codeBuilder = new StringBuilder();
        Date currentDate = new Date();
        
        for (int i = 0; i < segments.size(); i++) {
            SysCodingRuleSegment segment = segments.get(i);
            String segmentValue = generatePreviewSegmentValue(segment, currentDate);
            
            codeBuilder.append(segmentValue);
            
            // 添加分隔符（最后一段不加分隔符）
            if (i < segments.size() - 1 && StringUtils.isNotEmpty(codingRule.getSeparator())) {
                codeBuilder.append(codingRule.getSeparator());
            }
        }
        
        return codeBuilder.toString();
    }
    
    /**
     * 生成预览段值（不更新流水号）
     */
    private String generatePreviewSegmentValue(SysCodingRuleSegment segment, Date currentDate)
    {
        String segmentType = segment.getSegmentType();
        
        switch (segmentType) {
            case "CONSTANT":
                return segment.getSegmentValue();
                
            case "FIXED":
                return segment.getSegmentValue();
                
            case "DATE":
                SimpleDateFormat dateFormat = new SimpleDateFormat(segment.getDateFormat());
                return dateFormat.format(currentDate);
                
            case "RANDOM":
                return generateRandomNumber(segment.getSerialLength() != null ? segment.getSerialLength().intValue() : null);
                
            default:
                throw new RuntimeException("不支持的段类型: " + segmentType);
        }
    }

    /**
     * 批量生成编码
     */
    @Override
    public List<String> batchGenerateCode(Map<String, Object> params)
    {
        String tableName = (String) params.get("tableName");
        String fieldName = (String) params.get("fieldName");
        Integer count = (Integer) params.get("count");
        
        if (count == null || count <= 0) {
            count = 1;
        }
        
        List<String> codes = new ArrayList<>();
        for (int i = 0; i < count; i++) {
            String code = generateCode(tableName, fieldName, params);
            codes.add(code);
        }
        
        return codes;
    }

    /**
     * 获取编码规则统计信息
     */
    @Override
    public Map<String, Object> getCodingStats()
    {
        Map<String, Object> stats = new HashMap<>();
        
        // 统计编码规则总数
        List<SysCodingRule> allRules = sysCodingRuleMapper.selectSysCodingRuleList(new SysCodingRule());
        stats.put("totalRules", allRules.size());
        
        // 统计启用的编码规则数
        SysCodingRule enabledQuery = new SysCodingRule();
        enabledQuery.setStatus("0");
        List<SysCodingRule> enabledRules = sysCodingRuleMapper.selectSysCodingRuleList(enabledQuery);
        stats.put("enabledRules", enabledRules.size());
        
        // 流水号功能已移除
        stats.put("totalSerialRecords", 0);
        
        return stats;
    }

    /**
     * 验证编码规则配置
     */
    @Override
    public boolean validateCodingRule(Map<String, Object> params)
    {
        String tableName = (String) params.get("tableName");
        String fieldName = (String) params.get("fieldName");
        
        if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(fieldName)) {
            return false;
        }
        
        SysCodingRule codingRule = findCodingRule(tableName, fieldName);
        return codingRule != null;
    }

    /**
     * 复制编码规则
     */
    @Override
    @Transactional
    public boolean copyCodingRule(Long ruleId, String newRuleName)
    {
        // 查询原规则
        SysCodingRule originalRule = sysCodingRuleMapper.selectSysCodingRuleByRuleId(ruleId);
        if (originalRule == null) {
            return false;
        }
        
        // 创建新规则
        SysCodingRule newRule = new SysCodingRule();
        newRule.setRuleName(newRuleName);
        newRule.setTableName(originalRule.getTableName());
        newRule.setFieldName(originalRule.getFieldName() + "_copy");
        newRule.setSeparator(originalRule.getSeparator());
        newRule.setStatus("1"); // 默认禁用
        newRule.setRemark("复制自: " + originalRule.getRuleName());
        newRule.setCreateTime(DateUtils.getNowDate());
        
        int result = sysCodingRuleMapper.insertSysCodingRule(newRule);
        if (result <= 0) {
            return false;
        }
        
        // 复制规则段
        SysCodingRuleSegment querySegment = new SysCodingRuleSegment();
        querySegment.setRuleId(ruleId);
        List<SysCodingRuleSegment> originalSegments = sysCodingRuleSegmentMapper.selectSysCodingRuleSegmentList(querySegment);
        
        for (SysCodingRuleSegment originalSegment : originalSegments) {
            SysCodingRuleSegment newSegment = new SysCodingRuleSegment();
            newSegment.setRuleId(newRule.getRuleId());
            newSegment.setSegmentOrder(originalSegment.getSegmentOrder());
            newSegment.setSegmentType(originalSegment.getSegmentType());
            newSegment.setSegmentValue(originalSegment.getSegmentValue());
            newSegment.setDateFormat(originalSegment.getDateFormat());
            newSegment.setTimestampLength(originalSegment.getTimestampLength());
            newSegment.setSerialLength(originalSegment.getSerialLength());
            newSegment.setSerialStart(originalSegment.getSerialStart());
            newSegment.setResetType(originalSegment.getResetType());
            newSegment.setCreateTime(DateUtils.getNowDate());
            
            sysCodingRuleSegmentMapper.insertSysCodingRuleSegment(newSegment);
        }
        
        return true;
    }

    /**
     * 启用/禁用编码规则
     */
    @Override
    public boolean toggleCodingStatus(Long ruleId, String status)
    {
        SysCodingRule rule = sysCodingRuleMapper.selectSysCodingRuleByRuleId(ruleId);
        if (rule == null) {
            return false;
        }
        
        rule.setStatus(status);
        rule.setUpdateTime(DateUtils.getNowDate());
        
        return sysCodingRuleMapper.updateSysCodingRule(rule) > 0;
    }

    /**
     * 导入编码规则
     */
    @Override
    public boolean importCoding(Map<String, Object> params)
    {
        // 这里可以实现从文件或其他数据源导入编码规则的逻辑
        // 暂时返回true表示功能预留
        return true;
    }
}